package me.zhengjie.gas.proto.recv;

import me.zhengjie.gas.proto.TankerComm;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;

public class E3Comm extends TankerComm {

    /**
     * 终端交易号
     */
    private int transactionId;

    /**
     * 升数
     */
    private String volume;

    /**
     * 金额
     */
    private String amount;

    /**
     * 加油机总累
     */
    private String totalLitres;

    /**
     * 单价
     */
    private String unitPrice;

    /**
     * 油品号
     */
    private int productNumber;

    /**
     * 员工号
     */
    private String employeeId;

    /**
     * 交易记录类型
     */
    private int transactionType;

    /**
     * 交易时间
     */
    private Calendar transactionTime;

    /**
     * 逻辑卡号
     */
    private String logicCardId;

    /**
     * 卡余额
     */
    private String cardBalance;

    /**
     * CTC
     */
    private int ctc;

    /**
     * 物理卡号
     */
    private String physicalCardId;

    /**
     * 挂牌价格
     */
    private String listedPrice;

    /**
     * 挂牌金额
     */
    private String listedAmount;

    /**
     * 站点编码
     */
    private String stationCode;

    public E3Comm() {
        Cmd = (byte) 0xE3;
    }

    @Override
    protected boolean decode() {
        byte[] data = getDATA();

        // 解析终端交易号
        transactionId = (int) byteToBcd(data, 1, 4);

        // 解析升数
        volume = byteToBcdString(data, 5, 4);

        // 解析金额
        amount = byteToBcdString(data, 9, 4);

        // 解析加油机总累
        totalLitres = byteToBcdString(data, 13, 5);;

        // 解析单价
        unitPrice = byteToBcdString(data, 18, 3);

        // 解析油品号
        productNumber = (int) byteToBcd(data, 21, 2);

        // 解析员工号
        employeeId = byteToBcdString(data, 23, 1);

        // 解析交易记录类型
        transactionType = (int) byteToBcd(data, 24, 1);

        // 解析日期时间
        try {
            transactionTime = byteToDateTime(data, 25, 7);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }

        // 解析逻辑卡号
        logicCardId = byteToHexString(data, 32, 4).replaceAll(" ", "");//String.format("%08X", byteToBcd(data, 32, 4));

        // 解析卡余额
        cardBalance = byteToBcdString(data, 36, 5);

        // 解析CTC
        ctc = (int) byteToBcd(data, 41, 2);

        // 解析物理卡号
        physicalCardId = byteToHexString(data, 43, 4).replaceAll(" ", "");//String.format("%08X", byteToBcd(data, 43, 4));

        // 解析挂牌价格
        listedPrice = byteToBcdString(data, 47, 3);

        // 解析挂牌金额
        listedAmount = byteToBcdString(data, 50, 4);

        // 解析站点编码
        stationCode = byteToHexString(data, 54, 2);

        return true;
    }

    @Override
    public byte[] encode() {
        byte[] data = new byte[56];

        data[0] = Cmd;
        byte[] bytes = stringToBcdByteArray(String.valueOf(transactionId), 4);
        System.arraycopy(bytes, 0, data, 1, bytes.length);

        bytes = stringToBcdByteArray(volume, 4);
        System.arraycopy(bytes, 0, data, 5, bytes.length);

        bytes = stringToBcdByteArray(amount, 4);
        System.arraycopy(bytes, 0, data, 9, bytes.length);

        bytes = stringToBcdByteArray(totalLitres, 5);
        System.arraycopy(bytes, 0, data, 13, bytes.length);

        bytes = stringToBcdByteArray(unitPrice, 3);
        System.arraycopy(bytes, 0, data, 18, bytes.length);

        bytes = stringToBcdByteArray(String.valueOf(productNumber), 2);
        System.arraycopy(bytes, 0, data, 21, bytes.length);

        bytes = stringToBcdByteArray(String.valueOf(employeeId), 1);
        System.arraycopy(bytes, 0, data, 23, bytes.length);

        bytes = stringToBcdByteArray(String.valueOf(transactionType), 1);
        System.arraycopy(bytes, 0, data, 24, bytes.length);

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddhhmmss");
        bytes = stringToBcdByteArray(dateFormat.format(transactionTime.getTime()), 7);
        System.arraycopy(bytes, 0, data, 25, bytes.length);

        bytes = stringToBcdByteArray(logicCardId, 4);
        System.arraycopy(bytes, 0, data, 32, bytes.length);

        bytes = stringToBcdByteArray(cardBalance, 5);
        System.arraycopy(bytes, 0, data, 36, bytes.length);

        bytes = stringToBcdByteArray(String.valueOf(ctc), 2);
        System.arraycopy(bytes, 0, data, 41, bytes.length);

        bytes = stringToBcdByteArray(physicalCardId, 4);
        System.arraycopy(bytes, 0, data, 43, bytes.length);

        bytes = stringToBcdByteArray(listedPrice, 3);
        System.arraycopy(bytes, 0, data, 47, bytes.length);

        bytes = stringToBcdByteArray(listedAmount, 4);
        System.arraycopy(bytes, 0, data, 50, bytes.length);

        bytes = stringToBcdByteArray(stationCode, 2);
        System.arraycopy(bytes, 0, data, 54, bytes.length);

        setDATA(data);
        return super.encode();
    }

    @Override
    public String toString() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String str = "终端交易号：" + transactionId + "\n" +
                "升数：" + volume + "\n" +
                "金额：" + amount + "\n" +
                "加油机总累：" + totalLitres + "\n" +
                "单价：" + unitPrice + "\n" +
                "油品号：" + productNumber + "\n" +
                "员工号：" + employeeId + "\n" +
                "交易记录类型：" + transactionType + "\n" +
                "日期时间：" + sdf.format(transactionTime.getTime()) + "\n" +
                "逻辑卡号：" + logicCardId + "\n" +
                "卡余额：" + cardBalance + "\n" +
                "CTC：" + ctc + "\n" +
                "物理卡号：" + physicalCardId + "\n" +
                "挂牌价格：" + listedPrice + "\n" +
                "挂牌金额：" + listedAmount + "\n" +
                "站点编码：" + stationCode;

        return str;
    }


    public int getTransactionId() {
        return transactionId;
    }

    public void setTransactionId(int transactionId) {
        this.transactionId = transactionId;
    }

    public String getVolume() {
        return volume;
    }

    public void setVolume(String volume) {
        this.volume = volume;
    }

    public String getAmount() {
        return amount;
    }

    public void setAmount(String amount) {
        this.amount = amount;
    }

    public String getTotalLitres() {
        return totalLitres;
    }

    public void setTotalLitres(String totalLitres) {
        this.totalLitres = totalLitres;
    }

    public String getUnitPrice() {
        return unitPrice;
    }

    public void setUnitPrice(String unitPrice) {
        this.unitPrice = unitPrice;
    }

    public int getProductNumber() {
        return productNumber;
    }

    public void setProductNumber(int productNumber) {
        this.productNumber = productNumber;
    }

    public String getEmployeeId() {
        return employeeId;
    }

    public void setEmployeeId(String employeeId) {
        this.employeeId = employeeId;
    }

    public int getTransactionType() {
        return transactionType;
    }

    public void setTransactionType(int transactionType) {
        this.transactionType = transactionType;
    }

    public Calendar getTransactionTime() {
        return transactionTime;
    }

    public void setTransactionTime(Calendar transactionTime) {
        this.transactionTime = transactionTime;
    }

    public String getLogicCardId() {
        return logicCardId;
    }

    public void setLogicCardId(String logicCardId) {
        this.logicCardId = logicCardId;
    }

    public String getCardBalance() {
        return cardBalance;
    }

    public void setCardBalance(String cardBalance) {
        this.cardBalance = cardBalance;
    }

    public int getCtc() {
        return ctc;
    }

    public void setCtc(int ctc) {
        this.ctc = ctc;
    }

    public String getPhysicalCardId() {
        return physicalCardId;
    }

    public void setPhysicalCardId(String physicalCardId) {
        this.physicalCardId = physicalCardId;
    }

    public String getListedPrice() {
        return listedPrice;
    }

    public void setListedPrice(String listedPrice) {
        this.listedPrice = listedPrice;
    }

    public String getListedAmount() {
        return listedAmount;
    }

    public void setListedAmount(String listedAmount) {
        this.listedAmount = listedAmount;
    }

    public String getStationCode() {
        return stationCode;
    }

    public void setStationCode(String stationCode) {
        this.stationCode = stationCode;
    }
}
